package com.example.routeplansystem.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.example.routeplansystem.anotation.UserPermissionConf;
import com.example.routeplansystem.constant.PageRes;
import com.example.routeplansystem.constant.ResponseStatus;
import com.example.routeplansystem.entity.bo.QuestionNodeExcelBO;
import com.example.routeplansystem.entity.dto.ResponseEntity;
import com.example.routeplansystem.entity.po.NodePojo;
import com.example.routeplansystem.entity.po.NodeRes;
import com.example.routeplansystem.entity.po.QuestionNodePojo;
import com.example.routeplansystem.exception.ServiceException;
import com.example.routeplansystem.service.NodeService;
import com.example.routeplansystem.utils.validation.insertAndUpdateGroup.Update;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("node")
@Api(tags = "中心点服务点模块")
@Slf4j
@UserPermissionConf
public class NodeController {

    @Autowired
    private NodeService nodeService;

    //删除方案中的指定点：
    @DeleteMapping("deleteNode")
    @ApiOperation("删除指定点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "nodeId", value = "点Id", dataType = "int", required = true),
            @ApiImplicitParam(name = "questionId", value = "问题Id", dataType = "int", required = true)
    })
    public ResponseEntity<String> deleteNode(@RequestParam("questionId") int questionId, @RequestParam("nodeId") int nodeId) {
        nodeService.deleteNodeByQuestionIdAndNodeId(questionId, nodeId);
        return new ResponseEntity(ResponseStatus.SUCCESS_RESPONSE, "删除成功！！！", null);
    }

    //清空指定方案的所有选点：
    @DeleteMapping("clearNodes")
    @ApiOperation("删除指定问题的所有坐标选点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "questionId", value = "问题Id", dataType = "int", required = true)
    })
    public ResponseEntity<String> clearNode(@RequestParam("questionId") int questionId) {
        nodeService.clearNodes(questionId);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "清空节点数据成功！！！", null);
    }


    //获取所有节点信息：
    @GetMapping("getQuestionNodes")
    @ApiOperation("获取某个问题所有的点信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "questionId", value = "问题Id", paramType = "query"),
    })
    @Validated
    public ResponseEntity<List<NodeRes>> getQuestionNodes(@NotNull(message = "questionId 不能为空") @RequestParam(
            "questionId") Integer questionId) {
        List<NodeRes> nodes = nodeService.getQuestionNodes(questionId);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "查询成功！", nodes);
    }

    @PostMapping("/setCenter")
    @ApiOperation("设置某点为中心点")
    public ResponseEntity setCenter(@RequestParam("questionId") Integer questionId, @RequestParam("nodeId") Integer nodeId, @RequestParam("isCenter") Integer isCenter) {
        nodeService.setCenter(questionId, nodeId, isCenter);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "设置成功", null);
    }


    @PostMapping("addQuestionNode")
    @ApiOperation("给某个问题添加点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "nodeId", dataType = "Integer", value = "点ID", required = true),
            @ApiImplicitParam(name = "questionId", dataType = "Integer", value = "点ID", required = true),
            @ApiImplicitParam(name = "isCenter", dataType = "Integer", value = "点ID", required = true)
    })
    public ResponseEntity<String> addQuestionNode(@RequestBody QuestionNodePojo questionNodePojo) {
        nodeService.insertQuestionNode(questionNodePojo);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "添加成功！！！", null);
    }
    //单纯点部分

    //单点上传：
    @PostMapping("/newClientNode")
    @ApiOperation("通过点击地图方式导入客户")
    @ApiImplicitParams({
//            @ApiImplicitParam(name = "userId", dataType = "Integer", value = "用户ID", required = true),
            @ApiImplicitParam(name = "nodeName", dataType = "string", value = "点名称", required = true),
            @ApiImplicitParam(name = "nodeAddress", dataType = "string", value = "点详细地址", required = true),
            @ApiImplicitParam(name = "lat", dataType = "double", value = "纬度", required = true),
            @ApiImplicitParam(name = "lng", dataType = "double", value = "经度", required = true)

    })
    public ResponseEntity<String> insertClientNode(@RequestAttribute(value = "userId", required = false) Integer userId,
                                                   @RequestBody NodePojo nodePojo) {
        nodePojo.setUserId(userId);
        //选取点（地图选点）：
        nodeService.insertClientNode(nodePojo);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "客户数据写入成功！！！", null);
    }

    //批量上传节点信息：
    @PostMapping("/newClientNodeBatch")
    @ApiOperation("批量导入点信息")
    public ResponseEntity<String> insertClientNodeBatch(@RequestAttribute(value = "userId", required = false) Integer userId,
                                                        @RequestBody List<NodePojo> nodePojos) {
        for (NodePojo nodePojo : nodePojos)
            nodePojo.setUserId(userId);
        nodeService.insertClientNodeBatch(nodePojos);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "节点数据写入成功！！！", null);
    }

    //通过文件上传选点：
    @PostMapping("/excelClientNodeInfo")
    @ApiOperation("通过Excel导点")
    public ResponseEntity<String> upload(@RequestAttribute(value = "userId", required = false) Integer userId,
                                         @RequestBody MultipartFile file, HttpServletRequest request) {
        List<Integer> list = nodeService.ClientNodeBatchImport(file, request, userId);
        String msg;
        if (list.isEmpty()) {
            msg = "插入成功";
        } else {
            msg = "有" + list.size() + "个节点插入失败！客户Id重复 : " + list.toString();
        }
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, msg, null);
    }

    //删除指定点：
    @DeleteMapping("deleteClientNode")
    @ApiOperation("删除指定点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "nodeId", value = "点Id", dataType = "int", required = true),
            @ApiImplicitParam(name = "questionId", value = "问题Id", dataType = "int", required = true)
    })
    public ResponseEntity<String> deleteClientNode(@RequestParam("nodeId") int nodeId) {
        nodeService.deleteNodeByNodeId(nodeId);
        return new ResponseEntity(ResponseStatus.SUCCESS_RESPONSE, "点删除成功！！！", null);
    }

    //修改节点信息：
    @PatchMapping("updateClientNode")
    @ApiOperation("修改点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "nodeId", dataType = "int", value = "点Id", required = true),
            @ApiImplicitParam(name = "userId", dataType = "int", value = "用户Id", required = true),
            @ApiImplicitParam(name = "nodeName", dataType = "string", value = "点名称", required = true),
            @ApiImplicitParam(name = "nodeAddress", dataType = "string", value = "点详细地址", required = true),
            @ApiImplicitParam(name = "lat", dataType = "double", value = "纬度", required = true),
            @ApiImplicitParam(name = "lng", dataType = "double", value = "经度", required = true),
            @ApiImplicitParam(name = "delFlag", dataType = "int", value = "是否删除，默认不删除")
    })
    public ResponseEntity updateClientNode(@RequestAttribute(value = "userId", required = false) Integer userId,
                                           @Validated(Update.class) @RequestBody List<NodePojo> nodes) {
        for (NodePojo nodePojo : nodes)
            nodePojo.setUserId(userId);
        nodeService.updateNode(nodes);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "修改点信息成功！！！", null);
    }


    //获取该用户对应的所有点
    @GetMapping("getClientNodes")
    @ApiOperation("获取userId对应用户的所有的点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户Id", paramType = "query"),
    })
    @Validated
    public ResponseEntity<List<NodePojo>> getClientNodes(@RequestAttribute(value = "userId", required = false) Integer userId) {
        List<NodePojo> nodes = nodeService.getNodesByUserId(userId);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "查询成功！", nodes);
    }

    @GetMapping("pageClientNodes")
    @ApiOperation("分页获取位置点信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前页数", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "Integer"),
            @ApiImplicitParam(name = "request", paramType = "query")
    })
    @Validated
    public ResponseEntity<PageRes<NodePojo>> pageClientNodes(@RequestAttribute(value = "userId", required = false) Integer userId,
                                                             @NotNull(message = "当前页数") @RequestParam("pageNum") Integer pageNum,
                                                             @NotNull(message = "每页数量") @RequestParam("pageSize") Integer pageSize) {
        PageRes<NodePojo> nodes = nodeService.pageClientNodes(pageNum, pageSize, userId);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "查询成功！", nodes);
    }

    @DeleteMapping("deleteClientNodesByUserId")
    @ApiOperation("获取userId删除对应用户的所有的点")
    @ApiImplicitParams({})
    @Validated
    public ResponseEntity deleteClientNodesByUserId(@RequestAttribute(value = "userId", required = false) Integer userId) {
        nodeService.deleteClientNodeByUserId(userId);
        return new ResponseEntity(ResponseStatus.SUCCESS_RESPONSE, "删除成功！", null);
    }

    @DeleteMapping("batch")
    @ApiOperation("批量删除点")
    public ResponseEntity<Integer> batchDeleteNode(@RequestAttribute(value = "userId", required = false) Integer userId,
                                                   @RequestBody List<Integer> nodeIdList) {
        if (nodeIdList.isEmpty()) {
            throw new ServiceException("没有需要删除的客户");
        }
        Integer affect = nodeService.batchRemove(userId, nodeIdList);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "删除了" + affect + "个客户", affect);
    }

    @DeleteMapping("batch/{questionId}")
    @ApiOperation("批量删除某个问题的点")
    public ResponseEntity<Integer> batchRemoveWithQuestionId(@PathVariable("questionId") Integer questionId,
                                                             @RequestBody List<Integer> nodeIdList) {
        if (nodeIdList.isEmpty()) {
            throw new ServiceException("没有需要删除的点");
        }
        Integer affect = nodeService.batchRemoveWithQuestionId(questionId, nodeIdList);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "删除了" + affect + "个点", affect);
    }


    @PostMapping("fuzzyMatchingClientNode")
    @ApiOperation("模糊匹配查询点")
    @ApiImplicitParams({})
    @Validated
    public ResponseEntity<PageRes<NodePojo>> fuzzyMatchingClientNode(
            @RequestAttribute(value = "userId", required = false) Integer userId,
            @NotNull(message = "当前页数") @RequestParam("pageNum") Integer pageNum,
            @NotNull(message = "每页数量") @RequestParam("pageSize") Integer pageSize,
            @NotNull(message = "用来匹配的信息") @RequestParam("partInfo") String partInfo) {
        PageRes<NodePojo> nodes = nodeService.fuzzyMatchingClientNode(partInfo, userId, pageNum, pageSize);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "查询成功！", nodes);
    }

    //批量添加点到问题
    @PostMapping("batch/{questionId}")
    @ApiOperation("通过list批量添加点到问题")
    public ResponseEntity<Integer> addNodeToQuestion(@PathVariable("questionId") Integer questionId,
                                                     @RequestBody List<Integer> nodeIdList) {
        Integer affect = nodeService.batchInsertToQuestion(questionId, nodeIdList);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "添加了" + affect + "个点", affect);
    }

    @PostMapping("excelImport/{questionId}")
    @ApiOperation("通过excel批量导入客户到该问题")
    public ResponseEntity<List<QuestionNodeExcelBO>> NodeFileToQuestion(
            @RequestAttribute(value = "userId", required = false) Integer userId,
            @RequestBody MultipartFile file, @PathVariable("questionId") Integer questionId) {
        if (file.isEmpty()) throw new ServiceException("文件不能为空");
        List<QuestionNodeExcelBO> list = nodeService.QuestionNodeBatchImport(userId, file, questionId);
        String msg;
        if (list.isEmpty()) {
            msg = "插入成功";
            return new ResponseEntity<List<QuestionNodeExcelBO>>(ResponseStatus.SUCCESS_RESPONSE, msg, null);
        } else {
            msg = "有" + list.size() + "个客户未找到！全部取消插入，请现在客户管理中导入客户";
            return new ResponseEntity<List<QuestionNodeExcelBO>>(ResponseStatus.USER_OPERATION_ERROR, msg, list);
        }

    }

    //批量添加中心点
    @PutMapping("batch/center/{questionId}")
    @ApiOperation("批量设置中心点")
    public ResponseEntity<Integer> setCenterNodes(@PathVariable("questionId") Integer questionId,
                                                  @RequestBody List<Integer> nodeIdList) {
        Integer affect = nodeService.setCenterNodes(questionId, nodeIdList);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "设置了" + affect + "个中心点", affect);
    }

    @GetMapping("getdemand")
    @ApiOperation("获得客户的需求量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "questionId", value = "问题Id", dataTypeClass = Integer.class, required = true),
            @ApiImplicitParam(name = "nodeId", value = "用户Id", dataTypeClass = Integer.class, required = true)
    })
    public ResponseEntity<Float> getdemand(@RequestParam("questionId") Integer questionId,
                                           @RequestParam("nodeId") Integer nodeId) {
        Float demand = nodeService.getDemand(questionId, nodeId);
        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "", demand);
    }

    @PostMapping("setdemand")
    @ApiOperation("设置该客户的需求量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "questionId", value = "问题Id", dataTypeClass = Integer.class, required = true),
            @ApiImplicitParam(name = "nodeId", value = "用户Id", dataTypeClass = Integer.class, required = true),
            @ApiImplicitParam(name = "demand", value = "需求量", dataTypeClass = Float.class, required = true)
    })
    public ResponseEntity setdemand(@RequestParam("questionId") Integer questionId,
                                    @RequestParam("nodeId") Integer nodeId,
                                    @RequestParam("demand") Float demand) {
        Integer flag = nodeService.setDemand(new QuestionNodePojo(questionId, nodeId, demand));
        if (flag == 1) {
            return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "添加成功", null);
        } else {
            return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "该客户在该问题中不存在", null);
        }
    }
}